package com.twu.biblioteca;

import java.io.*;
import java.util.*;

public class BibliotecaApp {

    private  PrintStream printStream;
    private  BufferedReader bufferedReader;
    private  Library library;
    private String libraryNumber;
    private String userPassword;
    private String userDetails;
    private Map<Integer,String> menu;
    private  boolean loginStatus;
    public final static int MENU_OPTION_LIST_BOOKS = 1;
    public final static int MENU_OPTION_CHECKOUT_BOOK = 2;
    public final static int MENU_OPTION_RETURN_BOOK = 3;
    public final static int MENU_OPTION_LIST_MOVIES = 4;
    public final static int MENU_OPTION_CHECKOUT_MOVIE = 5;
    public final static int MENU_OPTION_EXIT = 6;
    public final static int MENU_OPTION_LOGIN = 7;
    public final static int MENU_OPTION_VIEW_PROFILE = 8;

    public BibliotecaApp(PrintStream printStream, Library library) {
        this.printStream = printStream;
        this.library = library;
        bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        loginStatus = false;
        libraryNumber = "222-3333";
        userPassword = "mayhem";
        userDetails = "Name: J Kuria\n" + "Email: jkuria@gmail.com\n" +
                "Phone: 0112223355\n";
        createMenuOptions();
        displayWelcomeMessage();
        printStream.println("************* Menu **********");
        displayMenu();
        printStream.println("*****************************");
        printStream.print("Select Option: ");
    }

    public static void main(String[] args) {
        BibliotecaApp bibliotecaApp = new BibliotecaApp(System.out,
                new Library(createBooks(),createMovies()));
        try {
            String s = bibliotecaApp.bufferedReader.readLine();
            int userSelection1 = Integer.parseInt(s);
            while (userSelection1 != MENU_OPTION_EXIT) {
                bibliotecaApp.executeOption(userSelection1);
                userSelection1 = Integer.parseInt(bibliotecaApp.bufferedReader.readLine());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public boolean isValidOption(int userSelection) {
        return menu.containsKey(userSelection);
    }

    private boolean isLoggedIn() {
        return loginStatus;
    }

    public void displayWelcomeMessage() {
        printStream.println("\nWelcome to Biblioteca");
    }

    public void displayAllBooks(Library library) {
        printStream.print(library.listBooks());
    }

    public void displayMenu() {
        Set<Integer> keys = menu.keySet();
        for (Integer key : keys) {
            String menuItem = key + ". " + menu.get(key);
            printStream.println(menuItem);
        }
    }

    private void createMenuOptions() {
        menu = new HashMap<Integer, String>();
        menu.put(MENU_OPTION_LIST_BOOKS, "List Books");
        menu.put(MENU_OPTION_CHECKOUT_BOOK, "Checkout Book");
        menu.put(MENU_OPTION_RETURN_BOOK, "Return Book");
        menu.put(MENU_OPTION_LIST_MOVIES, "List Movies");
        menu.put(MENU_OPTION_CHECKOUT_MOVIE, "Checkout Movie");
        menu.put(MENU_OPTION_EXIT, "Exit");
        menu.put(MENU_OPTION_LOGIN, "Login");
    }

    public void executeOption(int userSelection) throws IOException {
        switch (userSelection) {
            case MENU_OPTION_LIST_BOOKS:
                displayAllBooks(library);
                break;
            case MENU_OPTION_CHECKOUT_BOOK:
                if (!isLoggedIn()) {
                    printStream.println("Please login to checkout a book.");
                } else {
                    printStream.println("You chose to checkout a book: ");
                    printStream.println("Please enter a book you would like to checkout: ");
                    String nameOfBook = bufferedReader.readLine();
                    checkOutBook(library, nameOfBook);
                }
                break;
            case MENU_OPTION_RETURN_BOOK:
                if (!isLoggedIn()) {
                    printStream.println("Please login to return a book.");
                } else {
                    printStream.println("You chose to return a book.");
                    printStream.println("Please enter the book you would like to return: ");
                    String nameOfBook = bufferedReader.readLine();
                    returnBook(library, nameOfBook);
                }
                break;
            case MENU_OPTION_LIST_MOVIES:
                displayAvailableMovies(library);
                break;
            case MENU_OPTION_CHECKOUT_MOVIE:
                printStream.println("You chose to checkout a movie");
                printStream.println("Please enter a book you would like to checkout :");
                String nameOfMovie = bufferedReader.readLine();
                checkOutMovie(library, nameOfMovie);
                break;
            case MENU_OPTION_EXIT:
                System.exit(0);
                break;
            case MENU_OPTION_LOGIN:
                printStream.print("Please enter your library number: ");
                libraryNumber = bufferedReader.readLine();
                printStream.print("Please enter your password: ");
                userPassword = bufferedReader.readLine();
                login(libraryNumber, userPassword);
                break;
            case MENU_OPTION_VIEW_PROFILE:
                printStream.println(userDetails);
                break;
            default:
                printStream.println("Select a valid option!");
        }
    }

    public void checkOutBook(Library library, String title) {
        for(Book book : library.getBooks()) {
            if(book.getTitle().equals(title) && !book.isBorrowed()) {
                book.borrowed();
                printStream.println("Thank you! Enjoy the book.");
                return;
            }
        }
        printStream.println("That book is not available.");
    }

    public void returnBook(Library library, String title) {
        for(Book book: library.getBooks()) {
            if((book.getTitle().equals(title)) && book.isBorrowed()) {
                book.returned();
                printStream.println("Thank you for returning the book.");
                return;
            }
        }
        printStream.println("That is not a valid book to return.");
    }

    public void displayCheckedOutBooks(Library library) {
        for(Book book: library.getBooks()) {
            if(book.isBorrowed()) {
                printStream.println(book.getTitle());
            }
        }
    }

    public void displayAvailableMovies(Library library) {
        printStream.print(library.listMovies());
    }

    public void checkOutMovie(Library library, String name) {
        for (Movie movie: library.getMovies()) {
            if(movie.getName().equals(name)) {
                movie.borrowed();
                printStream.println("Thank you! Enjoy the movie.");
                return;
            }
        }
        printStream.println("That movie is not available.");
    }

    public void login(String number, String password) {
        if(number.equals(libraryNumber) && password.equals(userPassword)) {
            printStream.println("Login Successful.");
            loginStatus = true;
            addUserSpecificMenuItems();
            displayMenu();
        } else {
            printStream.println("Login Failed.");
        }
    }

    private void addUserSpecificMenuItems() {
        menu.put(MENU_OPTION_VIEW_PROFILE, "View Profile");
    }

    public String getUserDetails() {
        return userDetails;
    }

    private static List<Book> createBooks() {
        List<Book> books = new ArrayList<Book>();
        books.add(new Book("Desire of Ages"));
        books.add(new Book("Stay Alive All Your Life"));
        books.add(new Book("Great Expectations"));
        books.add(new Book("The River and The Source"));
        books.add(new Book("The Bible"));
        return books;
    }

    private static List<Movie> createMovies() {
        List<Movie> movies = new ArrayList<Movie>();
        movies.add(new Movie("The Pursuit of Happyness", 2006, "Gabriele Muccino", 8));
        movies.add(new Movie("To Sir with Love",1967,"James Clavell",8));
        movies.add(new Movie("Something the Lord Made",2004,"Joseph Sargent",9));
        return movies;
    }
}
